#![allow(unused)]

use std::marker::PhantomData;
use derive_new::new;

/// 为结构体生成一个[Bar::new]关联函数
/// # Example
/// ```
/// let _ = Bar::new(42, "Hello".to_owned());
/// ```
#[derive(new)]
struct Bar {
    a: i32,
    b: String,
}

/// 默认值可以通过 #[new(default)] 属性指定，
/// 该属性从构造函数中移除参数并使用 Default::default() 填充字段，
/// 或者通过 #[new(value = "..")] 指定
/// # Example
/// ```
/// let _ = Foo::new(true);
/// ```
#[derive(new)]
struct Foo {
    x: bool,
    #[new(value = "42")]
    y: i32,
    #[new(default)]
    z: Vec<String>,
}

/// `#[new(into)]` 属性将参数类型更改为 impl Into<T>，
/// 并将字段填充为 value.into()
/// # Example
/// ```
/// let _ = Bee::new("Hello");
/// ```
#[derive(new)]
struct Bee {
    #[new(into)]
    x: String,
}

/// 对于迭代器/集合，`#[new(into_iter = "T")]` 属性将参数类型更改为 impl IntoIterator<Item = T>，
/// 并将字段填充为 value.into_iter().collect()
/// # Example
/// ```
/// let _ = Cow::new([true, false]);
/// let _ = Cow::new(Some(true));
/// ```
#[derive(new)]
struct Cow {
    #[new(into_iter = "bool")]
    x: Vec<bool>,
}

/// 支持泛型类型；特别是，PhantomData<T> 字段将不会包含在参数列表中，并将自动初始化
/// # Example
/// ```
/// let _ = Generic::<i32, u8>::new("Hello");
/// ```
#[derive(new)]
struct Generic<'a, T: Default, P> {
    x: &'a str,
    y: PhantomData<P>,
    #[new(default)]
    z: T,
}

/// 对于枚举，为每个变体生成一个构造方法，类型名称将被转换为蛇形命名；
/// 否则，所有针对结构体的支持特性也适用于枚举变体
/// # Example
/// ```
/// let _ = Enum::new_first_variant();
/// let _ = Enum::new_second_variant(true);
/// let _ = Enum::new_third_variant(42);
/// ```
#[derive(new)]
enum Enum {
    FirstVariant,
    SecondVariant(bool, #[new(default)] u8),
    ThirdVariant { x: i32, #[new(value = "vec![1]")] y: Vec<u8> }
}

/// 默认情况下，生成的构造函数将是[pub]。然而，
/// 您可以使用 `#[new(visibility = "...")]` 属性来控制构造函数的可见性
/// + `#[new(visibility = "pub(crate)")]` [crate] 可见构造函数
/// + `#[new(visibility = "")]` 私有构造函数
#[derive(new)]
#[new(visibility = "pub(crate)")]
pub struct Fly {
    a: i32,
    b: String,
}

fn main() {
    let _ = Generic::<i32, u8>::new("Hello");
}
